/********************************************************************************
 * Project Name		[JavaEE_Web]
 * File Name     	[ForEachTag.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package jsp.tag.cases;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * 模拟<c:foreach>标签<br/>
 * 
 * 标签有两个属性: items[集合类型, Object)], var[String类型]
 * 
 * 遍历items对应的集合把正在遍历的对象放入到pageContext中<br/>
 * 键: var, 值: 正在遍历的对象<br/>
 * 把标签体的内容直接输出到页面上<br/>
 * 
 * Known Issues:<br/>
 * 无法使用自定义Java类作为泛型参数, 下面的代码会抛出异常<br/>
 * <code>
 * <%
 *     List<Customer> customers = new ArrayList<>();
 * 
 *     for (int i = 0; i < 10; i++) {
 *         Customer customer = new Customer();
 *         customer.setId(i);
 *         customer.setName("cust-" + (i + 1));
 *         customer.setAddress("addr-" + (i + 1));
 *         customer.setPhone("1850510625" + i);
 *         customers.add(customer);
 *     
 *         pageContext.setAttribute("customers", customers);
 *     }
 * %>
 * <pre>
 * <table border="1" cellpadding="10" cellspacing="0">
 *     <tr>
 *         <th>ID</th>
 *         <th>Name</th>
 *         <th>Address</th>
 *         <th>Phone</th>
 *     </tr>
 *     <s:forEach items="${customers}" var="cust">
 *     <tr>
 *         <td>${cust.id}</td>
 *         <td>${cust.name}</td>
 *         <td>${cust.address}</td>
 *         <td>${cust.phone}</td>
 *     </tr>
 *     </s:forEach>
 * </table>
 * </pre>
 * </code>
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ForEachTag extends SimpleTagSupport {

	private Object items;
	private String var;
	private Collection collection; // 用于储存items中的数据;

	public void setItems(Object items) {
		if (items instanceof Collection) {
			collection = (Collection) items; // list, set
		} else if (items instanceof Map) {
			Map map = (Map) items;
			collection = map.entrySet();
		} else if (items.getClass().isArray()) {
			collection = new ArrayList();
			int length = Array.getLength(items);
			for (int i = 0; i < length; i++) {
				Object obj = Array.get(items, i);
				collection.add(obj);
			}
		}
		this.items = items;
	}

	public void setVar(String var) {
		this.var = var;
	}

	@Override
	public void doTag() throws JspException, IOException {
		// 遍历items集合
		if (items != null) {
			Iterator iter = collection.iterator();
			while (iter.hasNext()) {
				// 把正在遍历的对象放入 pageContext中
				this.getJspContext().setAttribute(var, iter.next());
				// 把标签体内容输出到页面
				this.getJspBody().invoke(null);
			}
		}
	}
}
